-- UICardBonus
-- Create by chendh Jun/02/2016
-- 密令界面

UICardBonus = class("UICardBonus",function()
    return cc.Layer:create()
end)

function UICardBonus.create()
    return UICardBonus.new();
end

-- 内部函数声明
local resize;
local PET_ID = 91;
local LIMIT_COUNT = 32;

-- 构造函数
function UICardBonus:ctor()
    self:setName("UICardBonus");

    -- 初始化
    local node = cc.CSLoader:createNode("layout/setting/CardBonus.csb");
    self:addChild(node);
    self.node = node;

    -- 需要显示在头部菜单上面
    self:setLocalZOrder(UIMgr.BONUS_NOTIFY_ZORDER + 1);

    -- 适配
    self:resize(node);

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    self:redraw();
end

-- 适配
function UICardBonus:resize(node)
    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 绘制
function UICardBonus:redraw()
    local node = self.node;

    -- 标题
    local titleLable = findChildByName(node, "CT/template/title");
    titleLable:setString(getLocStr("card_bonus_title"));
    TextStyleM.setTitleStyle(titleLable);

    -- 副标题
    local subHeadLable = findChildByName(node, "CT/template/subhead");
    subHeadLable:setString(getLocStr("card_bonus_subhead"));
    TextStyleM.setSubheadStyle(subHeadLable);

    -- 绘制史莱姆
    local petNode = findChildByName(node, "CT/pet");
    local headImg = findChildByName(petNode, "img_node");
    local modelNode = findChildByName(petNode, "model_node");
    local modelId = PetM.query(PET_ID, "default_model");
    local petModelConfig = PetM.queryModel(modelId);
    local iconPath = getHeroIconPath(petModelConfig["icon"]);
    local scale = petModelConfig["model_scale"] * 1.5;
    local offsetX = petModelConfig["offset_x"];
    local offsetY = petModelConfig["offset_y"];

    -- 如果有模型就创建没有，没有就使用静态图片
    self.modelNode = createHeroModel(modelId, headImg, modelNode,
        scale, iconPath,offsetX, offsetY);

    -- 创建密令输入框
    self.contentLabel = findChildByName(self.node, "CT/input_box/text");
    -- 创建一个EditBox来接受字符内容
    if isIosPlatform() then
        self:createEditBoxForIos();
    else
        self:createEditBox();
    end

    -- 绘制按钮
    self:redrawBtn();

    -- 史莱姆发言
    self:slimeTalk("init");
end

-- ios下创建EditBox
function UICardBonus:createEditBoxForIos()
    -- 创建一个输入框替代原先的txt
    local inputBox = findChildByName(self.node, "CT/input_box");
    local label = findChildByName(self.node, "CT/input_box/text");
    local editBoxSize = label:getContentSize();
    local editCardNo = ccui.EditBox:create(editBoxSize, "images/ui/login/1.png");
    editCardNo:setAnchorPoint(cc.p(0, 1));
    editCardNo:setPosition(label:getPosition());

    editCardNo:setFontName(getLocFontName());
    editCardNo:setFontSize(TextStyleM.TEXT_SIZE_SMALL2 + 2);
    editCardNo:setPlaceholderFontColor(TextStyleM.TEXT_COLOR_DARK_BROWN);
    editCardNo:setPlaceholderFontSize(TextStyleM.TEXT_SIZE_SMALL2 + 2);
    editCardNo:setPlaceHolder(getLocStr("card_bonus_default"));
    editCardNo:setFontColor(TextStyleM.TEXT_COLOR_BLUE);
    editCardNo:setMaxLength(LIMIT_COUNT);
    editCardNo:setReturnType(cc.KEYBOARD_RETURNTYPE_RETURN);
    editCardNo:setScale(0.85);
    self.editCardNo = editCardNo;
    inputBox:addChild(editCardNo);

    self.cardNo = "";
    label:setFontSize(TextStyleM.TEXT_SIZE_SMALL2 + 2);
    label:setScale(0.85);
    label:setTextColor(TextStyleM.TEXT_COLOR_DARK_BROWN);
    label:setString(self.cardNo);

    -- 注册回调
    local function onEditboxEvent(ev)
        if ev == "began" then
            -- TODO
            local h = cc.Director:getInstance():getOpenGLView():getFrameSize().height;
            local CTNode = findChildByName(self.node, "CT");
            CTNode:setPositionY(h * 2 / 3);
        elseif ev == "ended" then
            -- TODO
        elseif ev == "changed" then
            -- TODO
        elseif ev == "return" then
            -- CT居中并缩放至合适大小
            AlignM.alignToCenter(self.node, "CT");

            self.cardNo = self.editCardNo:getText();

            self:redrawBtn();
        end
    end

    editCardNo:registerScriptEditBoxHandler(onEditboxEvent);
end

-- 其他平台创建EditBox
function UICardBonus:createEditBox()
    -- 创建一个输入框替代原先的txt
    local inputBox = findChildByName(self.node, "CT/input_box");
    local label = findChildByName(self.node, "CT/input_box/text");
    local editBoxSize = label:getContentSize();
    local editCardNo = ccui.EditBox:create(editBoxSize, "images/ui/login/1.png");
    editCardNo:setAnchorPoint(cc.p(0, 1));
    editCardNo:setPosition(label:getPosition());

    editCardNo:setFontName(getLocFontName());
    editCardNo:setFontSize(TextStyleM.TEXT_SIZE_SMALL2 + 2);
    editCardNo:setPlaceholderFontColor(TextStyleM.TEXT_COLOR_DARK_BROWN);
    editCardNo:setPlaceholderFontSize(TextStyleM.TEXT_SIZE_SMALL2 + 2);
    editCardNo:setPlaceHolder("");
    editCardNo:setFontColor(TextStyleM.TEXT_COLOR_BLUE);
    editCardNo:setMaxLength(LIMIT_COUNT);
    editCardNo:setReturnType(cc.KEYBOARD_RETURNTYPE_RETURN);
    editCardNo:setScale(0.85);
    self.editCardNo = editCardNo;
    inputBox:addChild(editCardNo);

    self.cardNo = getLocStr("card_bonus_default");
    label:setFontSize(TextStyleM.TEXT_SIZE_SMALL2 + 2);
    label:setScale(0.85);
    label:setTextColor(TextStyleM.TEXT_COLOR_DARK_BROWN);
    label:setString(self.cardNo);

    -- 注册回调
    local function onEditboxEvent(ev)
        if ev == "began" then
            -- 输入被打开
            if self.cardNo == getLocStr("card_bonus_default") then
                editCardNo:setText("");
            else
                editCardNo:setText(self.cardNo);
            end

            label:setVisible(false);
        elseif ev == "ended" then
            -- TODO
        elseif ev == "changed" then
            -- TODO
        elseif ev == "return" then
            self.cardNo = self.editCardNo:getText();

            editCardNo:setText("");

            label:setVisible(true);
            if string.len(self.cardNo) > 0 then
                label:setString(self.cardNo);

                label:setTextColor(TextStyleM.TEXT_COLOR_BLUE);
            else
                label:setString(getLocStr("card_bonus_default"));

                label:setTextColor(TextStyleM.TEXT_COLOR_DARK_BROWN);
            end

            self:redrawBtn();
        end
    end

    editCardNo:registerScriptEditBoxHandler(onEditboxEvent);
end

-- 绘制按钮
function UICardBonus:redrawBtn()
    local btnOk = findChildByName(self.node, "BT/btn_ok");

    if type(self.cardNo) == "string" and string.len(self.cardNo) > 0 then
        -- 底图退出灰白色
        setGrayMode(btnOk, false);
        btnOk:setTouchEnabled(true);
    else
        -- 底图进入灰白色
        setGrayMode(btnOk, true);
        btnOk:setTouchEnabled(false);
    end
end

-- 史莱姆发言
function UICardBonus:slimeTalk(tipId)
    local dialogNode = findChildByName(self.node, "CT/dialog");
    local nameLabel = findChildByName(dialogNode, "name");
    local textLabel = findChildByName(dialogNode, "panel/text");
    local tipConfig = CardBonusM.query(tipId);

    if not tipConfig then
        return;
    end

    local text = tipConfig["content"][math.random(#tipConfig["content"])];

    if type(self.cardInfo) == "table" and type(self.cardInfo[tipId]) == "string" then
        text = self.cardInfo[tipId];
    end

    TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_GREEN, false, nil, nil, nil, nil, TextStyleM.TEXT_SIZE_SMALL);
    nameLabel:setString(PetM.query(PET_ID, "name"));
    TextStyleM.setTextStyle(textLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_DARK_BROWN, false, nil, nil, nil, nil, TextStyleM.TEXT_SIZE_SMALL2);
    textLabel:setString(text);
    self.textLabel = textLabel;

    -- 收集字符列表
    self:collectLetters(text);

    dialogNode:setScale(0.01);
    dialogNode:setVisible(true);

    local scaleTo = cc.ScaleTo:create(0.3, 1);
    local callFunc = cc.CallFunc:create(function ()
            self:playTextEffect()
        end);
    dialogNode:runAction(cc.Sequence:create(scaleTo, callFunc));
end

-- 收集字符列表
function UICardBonus:collectLetters(text)
    local textLabel = self.textLabel;

    local count = string.getWCharCount(text);
    self.letters = {};

    local i = 0;
    local endPos = count - 1;
    local charPos = 0;
    local curPaddingCount = 0;
    while i <= endPos do
        local letter = textLabel:getVirtualRenderer():getLetter(i);
        local nextLetter = textLabel:getVirtualRenderer():getLetter(i+1);
        if letter then
            -- 初始所有字符置为不可见
            letter:setOpacity(0);

            -- 加入到字符列表
            table.insert(self.letters, 1, letter);
        else
            if nextLetter ~= nil and not string.isBreakLineChar(text, charPos-curPaddingCount) then
                -- 如果是系统自动添加的换行符，需要把结束位置往后挪
                endPos = endPos + 1;
                curPaddingCount = curPaddingCount + 1;
            end
        end

        i = i + 1;
        charPos = charPos + 1;
    end
end

-- 对话效果，一个字一个字慢慢播放
function UICardBonus:playTextEffect()
    local function play()
        if #self.letters > 0 then
            local letter = self.letters[#self.letters];
            table.remove(self.letters, #self.letters);
            local fadeIn = cc.FadeIn:create(0.1);
            local callFunc = cc.CallFunc:create(function()
                if 0 == #self.letters then
                    -- 标记字体播放完成
                    self.isFinished = true;
                end
            end);

            self.isFinished = false;
            letter:runAction(cc.Sequence:create(fadeIn, callFunc));
            performWithDelay(self.textLabel, play, 0.01);
        end
    end

    play();
end

-- 文字立刻显示
function UICardBonus:skipSection()
    self.textLabel:stopAllActions();

    if self.letters == nil then
        return;
    end

    while #self.letters > 0 do
        local letter = self.letters[#self.letters];
        table.remove(self.letters, #self.letters);
        letter:setOpacity(255);

        if 0 == #self.letters then
            -- 标记字体播放完成
            self.isFinished = true;
        end
    end
end

-- 播放奖励效果
function UICardBonus:playBonusEffect(cardInfo)
    local bonusNode = findChildByName(self.node, "CT/bonus1");

    local delay = cc.DelayTime:create(0.5);
    local scaleX = bonusNode:getScaleX();
    local scaleY = bonusNode:getScaleY();
    local scaleDown = cc.ScaleTo:create(0.1, scaleX, 0.9 * scaleY);
    local scaleUp = cc.ScaleTo:create(0.05, scaleX, scaleY);
    local moveUp1 = cc.EaseOut:create(cc.MoveBy:create(0.2, cc.p(0, 60)), 2.5);
    local moveDown = cc.EaseIn:create(cc.MoveBy:create(0.2, cc.p(0, -60)), 2.5);
    local scaleDown2 = cc.ScaleTo:create(0.05, scaleX, 0.8 * scaleY);
    local scaleUp2 = cc.ScaleTo:create(0.1, scaleX, scaleY);

    local callFunc = cc.CallFunc:create(function ()
        -- 显示获得奖励框
        showBonusNotifyForm(nil, cardInfo["bonus"], nil, nil);
    end)

    bonusNode:runAction(cc.Sequence:create(delay, scaleDown, scaleUp, moveUp1, moveUp2, moveDown, scaleDown2, scaleUp2, callFunc));
end

-- 注册事件处理回调函数
function UICardBonus:registerEventCallback()
    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            cclog("UICardBonus 界面析构清理");
            EventMgr.removeAll("UICardBonus");
        elseif eventType == "enter" then

        end
    end);

    -- 注册领取密令奖励的事件回调
    EventMgr.register("UICardBonus", event.CARD_BONUS, function(args)
        local result = args.result;
        local cardInfo = args.cardInfo;
        self.cardInfo = cardInfo;

        if type(result) == "string" then
            -- 失败了

            -- 失败发言
            self:slimeTalk(result);
        else
            -- 成功了

            -- 成功的发言
            if type(cardInfo["bonus_tip"]) == "string" and
                string.len(cardInfo["bonus_tip"]) > 0 then
                self:slimeTalk(cardInfo["bonus_tip"]);
            else
                self:slimeTalk("do_bonus");
            end

            -- 奖励表现
            self:playBonusEffect(cardInfo);
        end
    end);

    -- 关注领取老玩家召回礼包的事件回调
    EventMgr.register("UICardBonus", event.TAKE_RECALL_GIFT, function(args)
        if args["rule"] ~= "card_bonus" then
            return;
        end
        
        local result = args["result"];
        local giftId = args["giftId"];
        local tipId  = "take_recall_gift";

        local tip;
        if result == 1 then
            tip = RecallGiftM.query(giftId, "success_tip");
        else
            tip = RecallGiftM.query(giftId, "failed_tip");
        end

        self.cardInfo[tipId] = tip;

        -- 发言
        self:slimeTalk(tipId);
    end);
end

-- 执行下指令
function UICardBonus:debug_command()
    local args = string.explode(self.cardNo);

    if sizeof(args) < 2 then
        return;
    end

    -- 如果不是./cmd开头的
    if args[1] ~= "./cmd" then
        return;
    end

    -- 不期望能做太多东西，避免滥用，暂时枚举
    if args[2] == "error_info" then
        -- 打开报错界面
        local uiError = UIErrorInfo.create();
        if uiError then
            UIMgr.getCurrentScene():addForm(uiError);
            return true;
        end
    end
end

-- 注册点击事件
function UICardBonus:registerTouchEvent()
    local BT = findChildByName(self.node, "BT");

    -- 注册返回按钮点击事件
    local btnBack = findChildByName(BT, "btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_return");

            UIMgr.getCurrentScene():removeFormByName("UICardBonus");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 注册确定按钮点击事件
    local btnOk = findChildByName(BT, "btn_ok");
    local function onOkClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");

            -- 拦截掉了
            if self:debug_command() then
                return;
            end

            if type(self.cardNo) == "string" and string.len(self.cardNo) > 0 then
                CardBonusM.fetchCardBonus(self.cardNo);
            end
        end
    end
    btnOk:addTouchEventListener(onOkClick);
    TextStyleM.setTextStyle(btnOk, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnOk:setTitleText(getLocStr("btn_text_ok"));

    -- 注册对话框背景点击事件
    local dialogBg = findChildByName(self.node, "CT/dialog/bg");
    local function onDialogBgClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            self:skipSection();
        end
    end
    dialogBg:addTouchEventListener(onDialogBgClick);
end
